/*
This file is part of Jumpers.

Jumpers is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Jumpers is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Jumpers.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.chaoticengine.cgll.entity;

//~--- non-JDK imports --------------------------------------------------------

import java.util.List;
import org.chaoticengine.cgll.entity.component.ComponentManager;
import org.chaoticengine.cgll.entity.component.IComponent;

import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

/**
 * @author Matt v.d. Westhuizen
 *
 */
@Root(name="entity")
public class Entity {
    public static enum EntityType {
        NONE, // This entity is nothing special
        PLAYER, // This entity is the player avatar        
        ENEMY, // This entity is an antagonist
        BULLET, // This entity is a bullet
    };

    /** Unique identifier for this entity. */
    private int id = 0;

    /** Reference to the EntityManager that owns this entity. */
    private EntityManager owner = null;

    /** ComponentManager for controlling components of this entity. */
    private ComponentManager cm = new ComponentManager(this);

    /** The high-level type of the entity. */
    private EntityType type = EntityType.NONE;

    /** The entity position. */
    private Vector2f position = new Vector2f();

    /** The entity translation (if any). */
    private Vector2f translation = new Vector2f();

    /** The entity rotation in radians. */
    private float rotation = 0.0f;
    
    /** The front of the entity, expressed as a normalised vector. */
    private Vector2f direction = new Vector2f(0.0f, -1.0f);

    /** The bounding rectangle of the entity. */
    private Rectangle boundRect = new Rectangle(0.0f, 0.0f, 0.0f, 0.0f);

    public Entity() {

    }

    @Attribute(name="id", required=false)
    public int getId() {
        return (id);
    }

    @Attribute(name="id", required=false)
    public void setId(int id) {
        this.id = id;
    }

    public ComponentManager getComponentManager() {
        return (this.cm);
    }

    @ElementList(name="components", entry="component", required=false)
    public List<IComponent> getComponents() {
        return(cm.getComponents());
    }

    @ElementList(name="components", entry="component", required=false)
    public void setComponents(List<IComponent> comps) {
        cm.setComponents(comps);
        EntityManager.getInstance().updateCapabilities(this);
    }

    @Element(name="position", required=false)
    public Vector2f getPosition() {
        return (this.position.copy());
    }

    @Element(name="position", required=false)
    public void setPosition(Vector2f position) {
        this.position = position;

        // Update bounding rectangle
        this.boundRect.setX(position.x);
        this.boundRect.setY(position.y);
    }

    /**
     * @param owner the owner to set
     */
    public void setOwner(EntityManager owner) {
        this.owner = owner;
    }

    /**
     * @return the owner
     */
    public EntityManager getOwner() {
        return owner;
    }

    /**
     * @param translation the translation to set
     */
    @Element(name="translation", required=false)
    public void setTranslation(Vector2f translate) {
        this.translation = translate;
    }

    /**
     * @return the translation
     */
    @Element(name="translation", required=false)
    public Vector2f getTranslation() {
        return translation.copy();
    }

    /**
     * @param rotation the rotation to set
     */
    @Element(name="rotation", required=false)
    public void setRotation(float rotation) {
        this.rotation = rotation;
        this.direction.setTheta(rotation);
    }

    /**
     * @return the rotation
     */
    @Element(name="rotation", required=false)
    public float getRotation() {
        return rotation;
    }

    /**
     * @return the current facing direction
     */
    @Element(name="direction", required=false)
    public Vector2f getDirection() {
        return(direction.copy());
    }

    /**
     * @param dir the direction to set
     */
    @Element(name="direction", required=false)
    public void setDirection(Vector2f dir) {
        this.direction = dir.copy();
        this.rotation = (float) this.direction.getTheta();
    }

    /**
     * @param rect the bounding rectangle to set
     */
    @Element(name="bounds", required=false)
    public void setBoundingRectangle(Rectangle rect) {
        this.boundRect = rect;
    }

    /**
     * @return the bounding rectangle
     */
    @Element(name="bounds", required=false)
    public Rectangle getBoundingRectangle() {
        return(boundRect);
    }

    @Element(name="type", required=false)
    public EntityType getType() {
        return type;
    }

    @Element(name="type", required=false)
    public void setType(EntityType type) {
        this.type = type;
    }
    
    /**
     * Destroys this entity.
     */
    public void destroy() {
        owner.destroyEntity(this);
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
